iT邦幫忙

2026 iThome 鐵人賽

DAY 3
0
自我挑戰組

Python 爬蟲與資料分析實戰:從網路資料到資訊視覺化系列 第 16 篇

Day 16|Python 爬蟲實戰:整合書籍資料並匯出 CSV

  • 分享至 

  • xImage
  •  

今天想把之前學過的內容整合起來,從網頁取得書籍資訊,再把資料整理成統一的格式,最後儲存成 CSV 檔案。這樣後續就能直接使用 Pandas 進行資料分析,也可以避免每次執行爬蟲後,都要重新手動整理資料。
一、準備爬蟲環境
今天一樣使用 Google Colab,不需要另外建立本機環境。這次使用 Books to Scrape 作為練習網站,取得書籍標題、價格、評分和庫存狀態。
首先匯入需要使用的套件。
import requestsimport csvimport timefrom bs4 import BeautifulSoup

其中,Requests 負責取得網頁,BeautifulSoup 負責解析 HTML,CSV 用來儲存整理後的資料。time 則可以讓程式在請求之間稍微停頓,避免連續發送太多請求。
二、建立取得網頁的函式
先把取得網頁的功能獨立出來。這樣如果遇到網路問題,就可以在這個函式中處理,而不用把錯誤處理程式重複寫在每個爬取步驟裡。
def get_page(url): try: response = requests.get( url, timeout=10, headers={ "User-Agent": "Mozilla/5.0" } ) response.raise_for_status() return response.text except requests.RequestException as error: print("取得網頁失敗:", error) return None

這裡使用 timeout=10 設定等待時間,避免請求一直等待下去。raise_for_status() 則會在 HTTP 回應出現錯誤狀態時提出例外,再由 except 捕捉並顯示錯誤訊息。
如果網頁取得失敗,函式會回傳 None,讓後面的程式知道這次沒有取得有效的 HTML。
三、解析書籍資料
接下來建立解析資料的函式,將網頁中的書籍資訊整理成 Dictionary,再把每本書放進 List。
def parse_books(html, page_url): soup = BeautifulSoup(html, "html.parser") books = [] rating_map = { "One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5 } for item in soup.select("article.product_pod"): title_tag = item.select_one("h3 a") price_tag = item.select_one(".price_color") stock_tag = item.select_one(".availability") rating_tag = item.select_one("p.star-rating") if not title_tag or not price_tag: continue title = title_tag.get("title", "").strip() price_text = price_tag.get_text(strip=True) try: price = float( price_text.replace("£", "").strip() ) except ValueError: print("價格格式錯誤:", price_text) continue rating = None if rating_tag: rating_classes = rating_tag.get("class", []) for word in rating_classes: if word in rating_map: rating = rating_map[word] break availability = "" if stock_tag: availability = stock_tag.get_text( " ", strip=True ) books.append({ "title": title, "price": price, "rating": rating, "availability": availability, "source_url": page_url }) return books

這個函式主要做了幾件事情:

使用 BeautifulSoup 解析 HTML。
找出每本書的標題、價格、評分和庫存狀態。
將價格從字串轉成數字,方便後續計算。
將英文評分轉成 1~5 的數字。
將每本書整理成固定欄位的 Dictionary。
例如,原本的價格可能是 £51.77,整理後就會變成數字 51.77。這樣之後使用 Pandas 計算平均價格時,就不需要再另外處理價格符號。
四、整合爬取流程
前面已經完成取得網頁和解析資料的函式,接著將兩個功能串起來,並使用分頁連結繼續爬取其他頁面。
base_url = "https://books.toscrape.com/"current_url = base_urlall_books = []page_count = 0while current_url and page_count < 3: print("正在爬取:", current_url) html = get_page(current_url) if html is None: print("這一頁取得失敗,停止本次爬取。") break books = parse_books(html, current_url) all_books.extend(books) soup = BeautifulSoup(html, "html.parser") next_link = soup.select_one("li.next a") if next_link: current_url = requests.compat.urljoin( current_url, next_link.get("href") ) else: current_url = None page_count += 1 time.sleep(1)print("爬取完成!")print("總共取得", len(all_books), "筆書籍資料")print(all_books[:3])
這裡先限制最多爬取三頁,方便測試程式是否正常運作。all_books.extend(books) 會把每一頁取得的書籍資料加入同一個 List,而不是只保留最後一頁的結果。
另外,requests.compat.urljoin() 可以將下一頁的相對網址轉換成完整網址。如果下一頁連結不存在,程式就會停止分頁爬取。
等確認程式運作正常後,可以將 page_count < 3 改成單純的 while current_url,讓程式繼續爬取到沒有下一頁為止。實際執行時仍要遵守網站的使用規範,並控制請求頻率。
五、將資料儲存成 CSV
完成爬取後,接著把 all_books 儲存成 CSV 檔案。
if all_books: fieldnames = [ "title", "price", "rating", "availability", "source_url" ] with open( "books_day16.csv", "w", newline="", encoding="utf-8-sig" ) as file: writer = csv.DictWriter( file, fieldnames=fieldnames ) writer.writeheader() writer.writerows(all_books) print("CSV 檔案已儲存!")else: print("目前沒有資料可以儲存。")

這裡使用 csv.DictWriter(),可以直接把 Dictionary 寫入 CSV。writeheader() 會先寫入欄位名稱,而 writerows() 則會把所有書籍資料寫進檔案。
encoding="utf-8-sig" 可以降低使用 Excel 開啟 CSV 時出現中文亂碼的機率。
在 Google Colab 中,檔案會先儲存在目前的執行環境。若要下載到自己的電腦,可以再執行:
from google.colab import filesfiles.download("books_day16.csv")

執行後就可以下載 CSV 檔案,檢查爬取的資料是否完整。
六、檢查整理後的資料
最後,我想確認資料是否真的成功寫入檔案,也可以順便觀察幾筆資料。
import pandas as pddf = pd.read_csv("books_day16.csv")print(df.head())print("資料筆數:", len(df))print("平均價格:", df["price"].mean())print("最高價格:", df["price"].max())print("最低價格:", df["price"].min())

這裡使用 Pandas 讀取剛剛輸出的 CSV,並檢查前五筆資料、資料筆數和價格統計。由於前面已經將價格轉換成數字,因此可以直接計算平均值、最高價和最低價。
如果成功看到資料表和統計結果,就代表今天的爬蟲、資料整理與 CSV 匯出流程已經串接完成。
七、今天的實作心得
今天把之前學過的 Requests、BeautifulSoup、錯誤處理和資料清理整合在一起,也實際將爬取結果儲存成 CSV 檔案。
我發現爬蟲不只是把網頁上的文字抓下來而已,還需要考慮資料格式是否一致、某些欄位是否缺少,以及如何保存資料,讓後續分析可以繼續使用。
透過這次實作,我也更了解為什麼要把程式拆成不同的函式。當取得網頁、解析資料和儲存檔案各自負責不同工作時,程式會比較容易閱讀,也比較方便修改。
接下來會繼續學習如何面對請求失敗和網路不穩定的情況,並讓爬蟲在遇到錯誤時有更好的處理方式。


上一篇
Day 15|爬蟲資料的進一步處理:清理文字、價格與欄位
下一篇
Day 17|讓爬蟲更可靠:Retry 重試機制與錯誤處理
系列文
Python 爬蟲與資料分析實戰:從網路資料到資訊視覺化 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言